using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1
{
	public class Bdac
	{
		private int beatSampleRate;
		private double beatMSPerSample;
		private int beatMS400;
		private int beatMS1000;

		private int beatLgth;
		private int fidMark;

		private int ecgBufferLength;
		private int beatQueLength;
		private int[] ecgBuffer;
		private int ecgBufferIndex;
		private int[] beatQue;
		private int beatQueCount;
		private int rrCount = 0;
		private int initBeatFlag = 1;

		private QrsDet qrsDet;

		public Bdac ()
		{
			qrsDet = new QrsDet ();
			beatSampleRate = 100;
			beatMSPerSample = ((double)1000 / (double)beatSampleRate);
			beatMS400 = ((int)(400 / beatMSPerSample + 0.5));
			beatMS1000 = beatSampleRate;

			beatLgth = beatMS1000;
			fidMark = beatMS400;

			ecgBufferLength = 1000;
			beatQueLength = 10;
			ecgBuffer = new int[ecgBufferLength];
			ecgBufferIndex = 0;
			beatQue = new int[beatQueLength];
		}

		public void ResetBDAC ()
		{
			qrsDet.resetDetector ();
			rrCount = 0;
			initBeatFlag = 1;
			beatQueCount = 0;
		}


	public int BeatDetect (int ecgSample, int t)
		{
			int detectDelay;
			int rr = 0;
			int fidAdj = 0;

			// Store new sample in the circular buffer.

			ecgBuffer[ecgBufferIndex] = ecgSample;
			if (++ecgBufferIndex == ecgBufferLength)
				ecgBufferIndex = 0;

			// Increment RRInterval count.

			++rrCount;

			// Increment detection delays for any beats in the que.

			for (int i = 0; i < beatQueCount; ++i)
				++beatQue[i];

			// Run the sample through the QRS detector.

			detectDelay = qrsDet.qrsDet (ecgSample, t);
			if (detectDelay != 0) {
				beatQue[beatQueCount] = detectDelay;
				++beatQueCount;
			}

			// Return if no beat is ready for classification.

			if ((beatQue[0] < (beatLgth - fidMark) * (SampleRates.SampleRate / beatSampleRate)) || (beatQueCount == 0)) {
				return 0;
			}

			// Otherwise classify the beat at the head of the que.

			//  rr = RRCount - BeatQue[0];	// Calculate the R-to-R interval
			detectDelay = rrCount = beatQue[0];


			// Update the QUE.

			for (int i = 0; i < beatQueCount - 1; ++i)
				beatQue[i] = beatQue[i + 1];
			--beatQueCount;


			// Skip the first beat.

			if (initBeatFlag != 0) {
				initBeatFlag = 0;
				fidAdj = 0;
			// Classify all other beats.
			} else {
				fidAdj *= SampleRates.SampleRate / beatSampleRate;
			}


			// Limit the fiducial mark adjustment in case of problems with
			// beat onset and offset estimation.

			if (fidAdj > SampleRates.ms80)
				fidAdj = SampleRates.ms80; else if (fidAdj < -SampleRates.ms80)
				fidAdj = -SampleRates.ms80;

			if (detectDelay == 0) {
				rrCount += rr;
				return 0;
			} else
				return (detectDelay - fidAdj);

		}

	}
}
